package cc.rengu.igas.opms.core.service.trans.common;


import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.core.service.base.ManageService;
import cc.rengu.igas.opms.facade.bean.OrderInfoBean;
import cc.rengu.igas.opms.facade.bean.PayAcctInfoBean;
import cc.rengu.igas.opms.facade.request.GetPayOrderListRequest;
import cc.rengu.igas.opms.facade.response.GetPayOrderListResponse;
import cc.rengu.igas.share.core.model.PlatMchntInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.dao.MchntOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.PayOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MchntOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.PayOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.bean.PageInfo;
import cc.rengu.oltp.utility.bean.PageResult;
import cc.rengu.oltp.utility.util.AmountUtil;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 获取订单列表
 *
 * @author lenovo
 */
public class GetPayOrderListService extends ManageService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        GetPayOrderListRequest payOrderListRequest = new GetPayOrderListRequest();
        ConvertUtil.convertOutput(payOrderListRequest);
        return payOrderListRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        GetPayOrderListRequest payOrderListRequest = (GetPayOrderListRequest) request;
        GetPayOrderListResponse payOrderListResponse = new GetPayOrderListResponse();

        /*校验开始日期和结束日期*/
        String currentDate = DateUtil.getCurrentDate();
        /*开始时间不能大于当前时间*/
        if (null != payOrderListRequest.getStartDate() && !payOrderListRequest.getStartDate().isEmpty() && 0 < DateUtil.compareDate(payOrderListRequest.getStartDate(), currentDate)) {
            rglog.error(RespCodeEnum.DATE_START_GRENTERTHAN_CURRENT_ERROR.getRespCode() + "-" + RespCodeEnum.DATE_START_GRENTERTHAN_CURRENT_ERROR.getRespDesc());
            throw new BizException(RespCodeEnum.DATE_START_GRENTERTHAN_CURRENT_ERROR.getRespCode(), RespCodeEnum.DATE_START_GRENTERTHAN_CURRENT_ERROR.getRespDesc());
        }
        /*开始时间不能大于结束时间*/
        if (null != payOrderListRequest.getEndDate() && !payOrderListRequest.getEndDate().isEmpty() && null != payOrderListRequest.getStartDate() && !payOrderListRequest.getStartDate().isEmpty() && 0 < DateUtil.compareDate(payOrderListRequest.getStartDate(), payOrderListRequest.getEndDate())) {
            rglog.error(RespCodeEnum.DATE_START_GREATERTHAN_END_ERROR.getRespCode() + "-" + RespCodeEnum.DATE_START_GREATERTHAN_END_ERROR.getRespDesc());
            throw new BizException(RespCodeEnum.DATE_START_GREATERTHAN_END_ERROR.getRespDesc(), RespCodeEnum.DATE_START_GREATERTHAN_END_ERROR.getRespDesc());
        }

        /*开始日期和结束日期相差不能大于30天*/
        if (null != payOrderListRequest.getEndDate() && !payOrderListRequest.getEndDate().isEmpty() && null != payOrderListRequest.getStartDate() && !payOrderListRequest.getStartDate().isEmpty() && 0 < DateUtil.compareDate(payOrderListRequest.getEndDate(), DateUtil.getBaseDateOffsetDay(payOrderListRequest.getStartDate(), 30))) {
            rglog.error(RespCodeEnum.ENDDATE_MORE_STRDATE_ERROR.getRespCode() + "-" + RespCodeEnum.ENDDATE_MORE_STRDATE_ERROR.getRespDesc());
            throw new BizException(RespCodeEnum.ENDDATE_MORE_STRDATE_ERROR.getRespDesc(), RespCodeEnum.ENDDATE_MORE_STRDATE_ERROR.getRespDesc());
        }

        /*查询商户是否为平台商户*/
        MchntService mchntService = new MchntServiceImpl();
        rglog.debug("流程日志-校验平台商户:<{}>", payOrderListRequest.getPlatMchntNo());
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPageIndex((null == payOrderListRequest.getPageIndex() || payOrderListRequest.getPageIndex().isEmpty()) ? OpmsParamConstant.INT_ZERO : Integer.parseInt(payOrderListRequest.getPageIndex()));
        pageInfo.setPageSize((null == payOrderListRequest.getPageSize() || payOrderListRequest.getPageSize().isEmpty()) ? OpmsParamConstant.INT_NINE : Integer.parseInt(payOrderListRequest.getPageSize()));

        List<OrderInfoBean> orderInfoList = new ArrayList<>();
        /*查询用户订单表*/
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        PageResult pageResult = userOrderInfoMapper.selectUserOrderInfoByUserId(payOrderListRequest.getHeader().getInstId(), payOrderListRequest.getUserId(), payOrderListRequest.getStartDate(), payOrderListRequest.getEndDate(), pageInfo);
        if (null == pageResult || null == pageResult.getResult() || pageResult.getResult().isEmpty()) {
            rglog.info("无支付订单信息");
            payOrderListResponse.setTotalRows(OpmsParamConstant.STR_ZERO);
            payOrderListResponse.setTotalPage(OpmsParamConstant.STR_ZERO);
        } else {
            payOrderListResponse.setTotalRows(String.valueOf(pageResult.getPageInfo().getTotalRows()));
            payOrderListResponse.setTotalPage(String.valueOf(pageResult.getPageInfo().getTotalPage()));
            /*根据交易流水查询商户订单表和支付订单表*/
            MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
            PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
            List<Object> userOrderInfoList = pageResult.getResult();
            SysParamService sysParamService = new SysParamServiceImpl();
            SysParam sysParamInfo = sysParamService.getSysParamInfo(payOrderListRequest.getHeader().getInstId(), OpmsParamConstant.OPMS_SYS_PARAM, OpmsParamConstant.MCHNT_DISCOUNT_DISPLAY);
            for (Object object : userOrderInfoList) {
                UserOrderInfo userOrderInfo = (UserOrderInfo) object;
                OrderInfoBean orderInfoBean = new OrderInfoBean();
                List<MchntOrderInfo> mchntOrderInfoList = mchntOrderInfoMapper.selectMchntOrderInfoBySysSeqNum(userOrderInfo.getInstId(), userOrderInfo.getSysSeqNum());
                List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(userOrderInfo.getInstId(), userOrderInfo.getSysSeqNum());
                //商户信息
                if (null != mchntOrderInfoList && mchntOrderInfoList.size() == 1) {
                    /*非合并订单*/
                    orderInfoBean.setMchntNo(mchntOrderInfoList.get(0).getMchntNo());
                    orderInfoBean.setMchntName(mchntOrderInfoList.get(0).getMchntName());
                    orderInfoBean.setRefundAmt(AmountUtil.checkAmt(mchntOrderInfoList.get(0).getRefundAmt(), 2, false));
                } else if (null != mchntOrderInfoList && mchntOrderInfoList.size() > 1) {
                    /*合并订单支付 查询平台商户*/
                    PlatMchntInfo platMchntInfo = mchntService.getPlatMchntInfo(payOrderListRequest.getHeader().getInstId(), userOrderInfo.getGroupMchntNo());
                    if (null != platMchntInfo) {
                        orderInfoBean.setMchntNo(platMchntInfo.getPlatMchntNo());
                        orderInfoBean.setMchntName(platMchntInfo.getPlatMchntName());
                        orderInfoBean.setRefundAmt(AmountUtil.checkAmt(countRefundAmt(mchntOrderInfoList), 2, false));
                    }
                } else if (!StringUtil.isEmptyOrNull(userOrderInfo.getGroupMchntName())) {
                    //手机银行被扫和主扫他行码订单只有用户订单，没有商户订单，返回的商户名称使用用户订单边中的groupMchntName
                    orderInfoBean.setMchntNo(userOrderInfo.getGroupMchntNo());
                    orderInfoBean.setMchntName(userOrderInfo.getGroupMchntName());
                }
                //支付类型信息 过滤虚拟账户和营销的支付订单得到主流支付订单
                PayAcctInfoBean payAcctInfoBean = new PayAcctInfoBean();
                if (null != payOrderInfoList && !payOrderInfoList.isEmpty()) {
                    payOrderInfoList = payOrderInfoList.stream().filter(payorderInfo -> !ChannelEnum.MOMP.getChannelType().equals(payorderInfo.getMsgDstId())
                            && !ChannelEnum.ACCT.getChannelType().equals(payorderInfo.getMsgDstId())).collect(Collectors.toList());
                    if (!payOrderInfoList.isEmpty()) {
                        payAcctInfoBean.setTranAmt(payOrderInfoList.get(0).getRealPayAmt());
                        if ("P01PM007".equals(payOrderInfoList.get(0).getTxnNum())) {
                            if ("00".equals(payOrderInfoList.get(0).getBizType())) {
                                payAcctInfoBean.setPayType("10");
                                rglog.info("本行个人网关支付，支付订单号:<{}>", payOrderInfoList.get(0).getMchntOrderId());
                            } else if ("01".equals(payOrderInfoList.get(0).getBizType())) {
                                payAcctInfoBean.setPayType("11");
                                rglog.info("本行企业网关支付，支付订单号:<{}>", payOrderInfoList.get(0).getMchntOrderId());
                            }
                        } else if ("P01PM018".equals(payOrderInfoList.get(0).getTxnNum())) {
                            if ("00".equals(payOrderInfoList.get(0).getBizType())) {
                                payAcctInfoBean.setPayType("12");
                                rglog.info("银联个人网关支付，支付订单号:<{}>", payOrderInfoList.get(0).getMchntOrderId());
                            } else if ("01".equals(payOrderInfoList.get(0).getBizType())) {
                                payAcctInfoBean.setPayType("13");
                                rglog.info("银联企业网关支付，支付订单号:<{}>", payOrderInfoList.get(0).getMchntOrderId());
                            }
                        } else {
                            payAcctInfoBean.setPayType(payOrderInfoList.get(0).getPayType());
                        }
                        payAcctInfoBean.setPayerAcctType(payOrderInfoList.get(0).getPayerAcctType());
                        payAcctInfoBean.setPayerAcctInfo(payOrderInfoList.get(0).getPayeeAcctInfo());
                    }
                }

                if (StringUtil.isEmptyOrNull(payAcctInfoBean.getPayerAcctInfo())
                        && !StringUtil.isEmptyOrNull(userOrderInfo.getOrderExtraInfo())) {
                    JSONObject json = JSON.parseObject(userOrderInfo.getOrderExtraInfo());
                    payAcctInfoBean.setTranAmt(userOrderInfo.getOrderAmt());
                    payAcctInfoBean.setPayType(json.getString("payType"));
                    payAcctInfoBean.setPayerAcctType(json.getString("payerAcctType"));
                    payAcctInfoBean.setPayerAcctInfo(json.getString("payerAcctInfo"));
                }

                //响应信息
                orderInfoBean.setPayAcctInfo(payAcctInfoBean);
                orderInfoBean.setTransDate(userOrderInfo.getTxnDate());
                orderInfoBean.setTransTime(userOrderInfo.getTxnTime());
                orderInfoBean.setTxnNum(userOrderInfo.getTxnNum());
                orderInfoBean.setUserOrderId(userOrderInfo.getUserOrderId());
                orderInfoBean.setMchntOrderId(userOrderInfo.getMchntOrderId());
                orderInfoBean.setOrderCcy(userOrderInfo.getOrderCcy());
                if (sysParamInfo != null && sysParamInfo.getParamValue().contains(OpmsParamConstant.JNBKHJSH_PAY_CHANNEL_ID)) {
                    orderInfoBean.setDiscountAmt(AmountUtil.subtraction(userOrderInfo.getNeedPayAmt(), userOrderInfo.getRealPayAmt()));
                } else {
                    orderInfoBean.setDiscountAmt(AmountUtil.checkAmt(userOrderInfo.getRealDiscountAmt(), 2, false));
                }
                orderInfoBean.setOrderAmt(AmountUtil.checkAmt(userOrderInfo.getOrderAmt(), 2, false));
                orderInfoBean.setRealPayAmt(AmountUtil.checkAmt(userOrderInfo.getRealPayAmt(), 2, false));
                orderInfoBean.setOrderExpiryTime(userOrderInfo.getOrderExpiryTime());
                orderInfoBean.setOrderStatus(userOrderInfo.getOrderStatus());
                orderInfoBean.setOrderDesc(userOrderInfo.getOrderDesc());
                orderInfoBean.setBizStatus(userOrderInfo.getBizStatus());
                orderInfoList.add(orderInfoBean);
            }
        }

        //组应答信息
        payOrderListResponse.setOrderInfoList(orderInfoList);
        payOrderListResponse.setPageIndex(payOrderListRequest.getPageIndex());
        payOrderListResponse.setPageSize(payOrderListRequest.getPageSize());
        payOrderListResponse.setHeader(payOrderListRequest.getHeader());
        BizResponse<GetPayOrderListResponse> bizResponse = new BizResponse<>();
        bizResponse.setResult(payOrderListResponse);
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        GetPayOrderListResponse getPayOrderListResponse = (GetPayOrderListResponse) bizResponse.getResult();
        ConvertUtil.convertInput(getPayOrderListResponse);
    }

    /**
     * 累加退款金额
     *
     * @param opmsMchntOrderInfos 商户订单集合
     * @return 退款累计金额
     */
    private String countRefundAmt(List<MchntOrderInfo> opmsMchntOrderInfos) {
        String totleRefundAmt = "0";
        for (MchntOrderInfo opmsMchntOrderInfo : opmsMchntOrderInfos) {
            if (!StringUtil.isEmptyOrNull(opmsMchntOrderInfo.getRefundAmt())) {
                totleRefundAmt = AmountUtil.addition(totleRefundAmt, opmsMchntOrderInfo.getRefundAmt());
            }
        }
        return totleRefundAmt;
    }
}
